package cn.school.teacher.evaluation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.school.common.exception.ApiException;
import cn.school.teacher.evaluation.dao.TeacherEvaluationItemDao;
import cn.school.teacher.evaluation.dao.TeacherEvaluationScheItemDao;
import cn.school.teacher.evaluation.dao.TeacherEvaluationSchemeDao;
import cn.school.teacher.evaluation.entity.TeacherEvaluationItem;
import cn.school.teacher.evaluation.entity.TeacherEvaluationScheItem;
import cn.school.teacher.evaluation.entity.rspdo.EvaluationItemRspDo;
import cn.school.teacher.evaluation.service.EvaluationItemService;
import cn.school.teacher.evaluation.vo.ItemNodeVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("EvaluationItemService")
public class EvaluationItemServiceImpl extends ServiceImpl<TeacherEvaluationItemDao, TeacherEvaluationItem> implements EvaluationItemService {
    @Autowired
    private TeacherEvaluationScheItemDao teacherEvaluationScheItemDao;
    @Autowired
    private TeacherEvaluationSchemeDao teacherEvaluationSchemeDao;
    @Autowired
    private TeacherEvaluationItemDao teacherEvaluationItemDao;


    @Override
    public List<ItemNodeVo> getListByScheId(Long tescId) {
        List<EvaluationItemRspDo> evaluationItems = this.teacherEvaluationItemDao.getList(tescId);
        List<ItemNodeVo> list = new ArrayList<>();
        HashMap<Long, ItemNodeVo> levelOneMap = new HashMap<>();
        if (evaluationItems != null && evaluationItems.size() != 0) {
            ItemNodeVo nodeVo = null;
            ItemNodeVo nodeParentVo = null;
            for (int i = 0, size = evaluationItems.size(); i < size; i++) {
                nodeVo = new ItemNodeVo();
                BeanUtils.copyProperties(evaluationItems.get(i), nodeVo);
                if (evaluationItems.get(i).getTeitParentId() == null) {
                    list.add(nodeVo);
                    levelOneMap.put(nodeVo.getId(), nodeVo);
                } else if (levelOneMap.containsKey(nodeVo.getTeitParentId())) {
                    nodeParentVo = levelOneMap.get(nodeVo.getTeitParentId());
                    if (nodeParentVo.getChildren() == null) {
                        List<ItemNodeVo> childrenList = new ArrayList<>();
                        childrenList.add(nodeVo);
                        nodeParentVo.setChildren(childrenList);
                    } else {
                        nodeParentVo.getChildren().add(nodeVo);
                    }
                }
            }
        }
        return list;
    }

    @Override
    public ItemNodeVo getById(Long teitId) {
        List<EvaluationItemRspDo> evaluationItems = this.teacherEvaluationItemDao.getById(teitId);
        if (evaluationItems != null && evaluationItems.size() != 0) {
            ItemNodeVo nodeVo = new ItemNodeVo();
            BeanUtils.copyProperties(evaluationItems.get(0), nodeVo);
            return nodeVo;
        } else {
            return null;
        }
    }

    @Override
    @Transactional
    public int update(Long id, ItemNodeVo itemNodeVo) {
        int count = 0;
        TeacherEvaluationItem teacherEvaluationItem = teacherEvaluationItemDao.selectById(itemNodeVo.getId());
        itemNodeVo.setId(id);
        BeanUtil.copyProperties(itemNodeVo, teacherEvaluationItem);
        count = this.teacherEvaluationItemDao.updateById(teacherEvaluationItem);

        TeacherEvaluationScheItem teacherEvaluationScheItem = this.teacherEvaluationScheItemDao.selectById(itemNodeVo.getTesiId());
        BeanUtil.copyProperties(itemNodeVo, teacherEvaluationScheItem);
        teacherEvaluationScheItem.setId(itemNodeVo.getTesiId());
        count = count + teacherEvaluationScheItemDao.updateById(teacherEvaluationScheItem);

        if (!this.checkPercent(itemNodeVo.getTescId())) {
            throw new ApiException("打分百分比不符合规则");
        }
        return count;
    }

    @Override
    @Transactional
    public int create(ItemNodeVo itemNodeVo) {
        TeacherEvaluationItem teacherEvaluationItem = new TeacherEvaluationItem();
        BeanUtil.copyProperties(itemNodeVo, teacherEvaluationItem);
        int count = this.teacherEvaluationItemDao.insert(teacherEvaluationItem);

        TeacherEvaluationScheItem teacherEvaluationScheItem = new TeacherEvaluationScheItem();
        BeanUtil.copyProperties(itemNodeVo, teacherEvaluationScheItem);
        teacherEvaluationScheItem.setTeitId(teacherEvaluationItem.getId());
        count = count + this.teacherEvaluationScheItemDao.insert(teacherEvaluationScheItem);

        if (!this.checkPercent(itemNodeVo.getTescId())) {
            throw new ApiException("打分百分比不符合规则");
        }

        return count;
    }


    @Transactional
    public boolean checkPercent(Long tescId) {
        List<EvaluationItemRspDo> evaluationItems = this.teacherEvaluationItemDao.getList(tescId);
        List<ItemNodeVo> list = new ArrayList<>();
        HashMap<Long, ItemNodeVo> levelOneMap = new HashMap<>();
        if (evaluationItems != null && evaluationItems.size() != 0) {
            ItemNodeVo nodeVo = null;
            ItemNodeVo nodeParentVo = null;
            for (int i = 0, size = evaluationItems.size(); i < size; i++) {
                nodeVo = new ItemNodeVo();
                BeanUtils.copyProperties(evaluationItems.get(i), nodeVo);
                if (evaluationItems.get(i).getTeitParentId() == null) {
                    list.add(nodeVo);
                    levelOneMap.put(nodeVo.getId(), nodeVo);
                } else if (levelOneMap.containsKey(nodeVo.getTeitParentId())) {
                    nodeParentVo = levelOneMap.get(nodeVo.getTeitParentId());
                    if (nodeParentVo.getChildren() == null) {
                        List<ItemNodeVo> childrenList = new ArrayList<>();
                        childrenList.add(nodeVo);
                        nodeParentVo.setChildren(childrenList);
                    } else {
                        nodeParentVo.getChildren().add(nodeVo);
                    }
                }
            }
        }
        // 校验
        if (levelOneMap.size() != 0) {
            Iterator<Long> it = levelOneMap.keySet().iterator();
            int sum = 0;
            while (it.hasNext()) {
                Long teitLong = it.next();
                ItemNodeVo nodeVo = levelOneMap.get(teitLong);
                if (nodeVo.getChildren() != null && nodeVo.getChildren().size() != 0) {
                    int levelTwoSum = nodeVo.getChildren().stream().mapToInt(ItemNodeVo::getTesiPercent).sum();
                    if (levelTwoSum > nodeVo.getTesiPercent()) {
                        return false;
                    }
                }

                sum += nodeVo.getTesiPercent();

                if (sum > 100) {
                    return false;
                }
            }
        }
        return true;
    }


    @Override
    @Transactional
    public int deleteByIds(Long[] ids) {
        int count = 0;
        if (ids != null && ids.length != 0) {
            List<Long> idList = Arrays.stream(ids).collect(Collectors.toList());
            count = this.baseMapper.deleteBatchIds(idList);
            LambdaQueryWrapper<TeacherEvaluationScheItem> teacherEvaluationScheItemWrapper = new LambdaQueryWrapper<>();
            teacherEvaluationScheItemWrapper.in(TeacherEvaluationScheItem::getTeitId, idList);
            this.teacherEvaluationScheItemDao.delete(teacherEvaluationScheItemWrapper);
        }
        return count;
    }
}
